﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace NumericalMethod
{
    public partial class ConvertingNumbers : ContentPane
    {
        

        private StatusForm mStatus;
        

        private BasedType userInput = BasedType.base10;
        private BasedType userOutput = BasedType.base2;


        string[] method = new string[6] { 
           "Decimal Number", 
           "Binary Number", 
           "Octal Number",
           "Hexadecimal Number",
           "Decimal Fraction",
           "Binary Fraction"
        };
        public ConvertingNumbers()
        {            
            InitializeComponent();
        }
        public override void OnLoad()
        {
            mStatus = new StatusForm();
            Parent.Controls.Add(mStatus);
            prepareData();
            mStatus.HidePanel(2);
        }


        private void prepareData()
        {            
            LoadValuesForInputTypeCombobox();            
        }

        private void LoadValuesForOutPutTypeCombobox(string input)
        {
            cboOutputType.Items.Clear();
            switch (input)
            {
                case "Decimal Number":
                    for (int i = 0; i < method.Length; i++)
                    {
                        if (method[i] != input && method[i] != "Decimal Fraction" && method[i] != "Binary Fraction")
                            cboOutputType.Items.Add(method[i]);                        
                    }
                    userInput = BasedType.base10;
                    break;
                case "Binary Number":
                    for (int i = 0; i < method.Length; i++)
                    {
                        if (method[i] != input && method[i] != "Decimal Fraction" && method[i] != "Binary Fraction")
                            cboOutputType.Items.Add(method[i]);
                    }
                    userInput = BasedType.base2;
                    break;
                case "Octal Number":
                    for (int i = 0; i < method.Length; i++)
                    {
                        if (method[i] != input && method[i] != "Decimal Fraction" && method[i] != "Binary Fraction")
                            cboOutputType.Items.Add(method[i]);
                    }
                    userInput = BasedType.base8;
                    break;
                case "Hexadecimal Number":
                    for (int i = 0; i < method.Length; i++)
                    {
                        if (method[i] != input && method[i] != "Decimal Fraction" && method[i] != "Binary Fraction")
                            cboOutputType.Items.Add(method[i]);
                    }
                    userInput = BasedType.base16;
                    break;
                case "Decimal Fraction":
                    cboOutputType.Items.Add("Binary Fraction");
                    userInput = BasedType.binaryFraction;
                    break;
                case "Binary Fraction":
                    cboOutputType.Items.Add("Decimal Fraction");
                    userInput = BasedType.decimalFraction;
                    break;
                default:
                    break;
            }            
            
            cboOutputType.SelectedIndex = 0;
        }

        private void LoadValuesForInputTypeCombobox()
        {
            cboInputType.Items.Clear();
            cboInputType.Items.AddRange(method);
            cboInputType.SelectedIndex = 0;
        }

        private void cboInputType_SelectedIndexChanged(object sender, EventArgs e)
        {
            LoadValuesForOutPutTypeCombobox(cboInputType.Text);
            txtInput.Clear();
            lblAnswer.Text = "";
            txtInput.Focus();
        }

        void txtInput_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            userInput = getUserEnum(cboInputType);
            switch (userInput)
            {
                case BasedType.base10:
                    if (!char.IsNumber(e.KeyChar) && e.KeyChar != '\b')
                    {
                        e.Handled = true;
                    }
                    break;
                case BasedType.base2:
                    if (!Numbers.IsBinaryNumber(e.KeyChar.ToString()) && e.KeyChar != '\b')
                        e.Handled = true;
                    break;
                case BasedType.base8:
                    if (!Numbers.IsOctalNumber(e.KeyChar.ToString()) && e.KeyChar != '\b')
                        e.Handled = true;
                    break;
                case BasedType.base16:
                    if (!Numbers.IsHexadecimalNumber(e.KeyChar.ToString()) && e.KeyChar != '\b')
                        e.Handled = true;
                    break;
                case BasedType.binaryFraction:
                    if (!Numbers.IsBinaryNumber(e.KeyChar.ToString()) && e.KeyChar != '\b')
                        e.Handled = true;
                    break;
                case BasedType.decimalFraction:
                    if (!Numbers.IsDecimalFractionNumber(e.KeyChar.ToString()) && e.KeyChar != '\b')
                        e.Handled = true;
                    break;
                default:
                    break;
            }
        }


        private void btnAnswer_Click(object sender, EventArgs e)
        {
            if (txtInput.Text.Trim() == "")
                return;

            userOutput = getUserEnum(cboOutputType);
            if (userInput == BasedType.base10)
            {
                lblAnswer.Text = Numbers.DecimalToBase(int.Parse(txtInput.Text), (int)userOutput);                                
            }
            if(userOutput == BasedType.base10)
            {
                
                lblAnswer.Text = Numbers.BaseToDecimal(txtInput.Text, (int)userInput).ToString(); 
                
            }
            if (userInput != BasedType.base10 && userOutput != BasedType.base10 && 
                userInput != BasedType.decimalFraction && userOutput != BasedType.binaryFraction &&
                userOutput != BasedType.decimalFraction && userInput != BasedType.binaryFraction)
            {
                decimal dNumber = Numbers.BaseToDecimal(txtInput.Text, (int)userInput);
                if (dNumber == decimal.MaxValue)
                {
                    mStatus.AppendOutput("Infinity..");
                    return;
                }
                else
                {
                    lblAnswer.Text = Numbers.DecimalToBase((int)dNumber, (int)userOutput);
                }
            }
            if (userInput == BasedType.binaryFraction)
            {
                //lblAnswer.Text = Numbers.decimalFractionToBinaryFraction(decimal.Parse(txtInput.Text), 2).ToString();
                decimal dNumber = Numbers.BaseToDecimal(txtInput.Text, 2);
                if (dNumber == decimal.MaxValue)
                {
                    mStatus.AppendOutput("Infinity..");
                    return;
                }
                else
                {
                    lblAnswer.Text = dNumber.ToString();
                }
            }
            if (userInput == BasedType.decimalFraction)
            {
                decimal dNumber = Numbers.decimalFractionToBinaryFraction(decimal.Parse(txtInput.Text), 2);
                if (dNumber == decimal.MaxValue)
                {
                    mStatus.AppendOutput("Infinity..");
                    return;
                }
                else
                {
                    lblAnswer.Text = dNumber.ToString();
                }
            }

            mStatus.AppendOutput(txtInput.Text + " [" + cboInputType.Text + "] = "
                + lblAnswer.Text + " [" + cboOutputType.Text + "]");
        }
        
        private BasedType getUserEnum(ComboBox cbo)
        {
            for (int i = 0; i < cbo.Items.Count; i++)
            {
                if (cbo.SelectedItem.ToString() == "Decimal Number")
                {
                    return BasedType.base10;
                }
                else if (cbo.SelectedItem.ToString() == "Binary Number")
                {
                    return BasedType.base2;
                }
                else if (cbo.SelectedItem.ToString() == "Octal Number")
                {
                    return BasedType.base8;
                }
                else if (cbo.SelectedItem.ToString() == "Hexadecimal Number")
                {
                    return BasedType.base16;
                }
                else if (cbo.SelectedItem.ToString() == "Decimal Fraction")
                {
                    return BasedType.decimalFraction;
                }
                else if (cbo.SelectedItem.ToString() == "Binary Fraction")
                {
                    return BasedType.binaryFraction;
                }
            }
            return BasedType.base10;
        }

        private void cboOutputType_SelectedIndexChanged(object sender, EventArgs e)
        {
            //userOutput = getUserOutPut(cboOutputType);
        }
        
    }
}
